// 防止相同的宏被重复定义
#ifndef _APPLICATION_H_
#define _APPLICATION_H_

// freertos 开源的 RTOS（实时操作系统）内核
#include <freertos/FreeRTOS.h>
#include <freertos/event_groups.h>
#include <freertos/task.h>

#include <string>
#include <mutex>
#include <list>

#include <opus_encoder.h>
#include <opus_decoder.h>
#include <opus_resampler.h>

#include "protocol.h"
#include "ota.h" // 系统升级管理
#include "background_task.h"

// 如果是ESP32S3版，引入唤醒词检测和音频处理器
#if CONFIG_IDF_TARGET_ESP32S3
#include "wake_word_detect.h"
#include "audio_processor.h"
#endif

#define SCHEDULE_EVENT (1 << 0)
#define AUDIO_INPUT_READY_EVENT (1 << 1)
#define AUDIO_OUTPUT_READY_EVENT (1 << 2)

enum ChatState {
    kChatStateUnknown,
    kChatStateIdle,
    kChatStateConnecting,
    kChatStateListening,
    kChatStateSpeaking,
    kChatStateUpgrading
};

#define OPUS_FRAME_DURATION_MS 60

class Application {
public:
    // 获取application实例
    static Application& GetInstance() {
        static Application instance;
        return instance;
    }
    // 删除拷贝构造函数和赋值运算符
    Application(const Application&) = delete;
    Application& operator=(const Application&) = delete;
    // 系统启动
    void Start();
    // 获取当前状态
    ChatState GetChatState() const { return chat_state_; }
    void Schedule(std::function<void()> callback);
    void SetChatState(ChatState state);
    void Alert(const std::string& title, const std::string& message);
    void AbortSpeaking(AbortReason reason);
    void ToggleChatState();
    void StartListening();
    void StopListening();
    void UpdateIotStates();
// 定义私有变量
private:
    Application();
    ~Application();

#if CONFIG_IDF_TARGET_ESP32S3
    WakeWordDetect wake_word_detect_;
    AudioProcessor audio_processor_;
#endif
    /*
    OTA（Over-the-AirTechnology）即空中下载技术，是通过移动通信的空中接口实现对移动终端设备及SIM卡数据进行远程管理的技术。
    OTA升级是物联网（IOT）产品设计的一个非常重要的部分，能够实现智能设备系统漏洞修复、系统升级，通过固件和软件的升级，提供更好的服务。
    OTA固件升级功能不仅能够更新固件，而且还能重新配置芯片上硬件资源。同时，设备固件可通过OTA固件升级流程获得更新的补丁和更多安全算法防范病毒攻击。
    */
    Ota ota_;
    std::mutex mutex_;
    std::list<std::function<void()>> main_tasks_;
    // 网络协议
    std::unique_ptr<Protocol> protocol_;
    EventGroupHandle_t event_group_;
    volatile ChatState chat_state_ = kChatStateUnknown;
    bool keep_listening_ = false;
    bool aborted_ = false;
    std::string last_iot_states_;

    // Audio encode / decode
    BackgroundTask background_task_;
    std::chrono::steady_clock::time_point last_output_time_;
    std::list<std::vector<uint8_t>> audio_decode_queue_;

    std::unique_ptr<OpusEncoderWrapper> opus_encoder_;
    std::unique_ptr<OpusDecoderWrapper> opus_decoder_;

    int opus_decode_sample_rate_ = -1;
    OpusResampler input_resampler_;
    OpusResampler reference_resampler_;
    OpusResampler output_resampler_;

    void MainLoop();
    void InputAudio();
    void OutputAudio();
    void ResetDecoder();
    void SetDecodeSampleRate(int sample_rate);
    void CheckNewVersion();

    void PlayLocalFile(const char* data, size_t size);
};

#endif // _APPLICATION_H_
